package com.sojson.util.properties;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;

import com.sojson.constant.ConstantCache;
import com.sojson.util.ExpUtil;
import com.sojson.util.StringUtil;
import com.sojson.util.properties.impl.PropertiesUtilImpl;

/**
 * Properties工具类
 *
 * @author liu
 * @date 2020-11-02
 */
public class PropertiesUtil {

    private static final PropertiesUtilInterface PROPERTIES_UTILS_INTERFACE = PropertiesUtilImpl.getInstances();

    // =======================================================================================================
    // ===============================================加载属性文件===============================================
    // =======================================================================================================
    /**  */
    public static final ResourcePatternResolver RESOLVER = new PathMatchingResourcePatternResolver();
    private static final ScriptEngine SE = new ScriptEngineManager().getEngineByName("JavaScript");

    /**
     * 读取resources下所有相同名字的properties文件，返回一个Properites对象
     *
     * @param fileName properties文件名（文件必须要在resources文件夹下）
     * @return 得到的对象
     * @throws IOException
     */
    public static Resource getResource(String fileName) throws IOException {
        return RESOLVER.getResource(fileName);
    }

    /**
     * 读取resources下所有相同名字的properties文件，返回一个Properites对象
     *
     * @param filePath 文件路径
     * @return 得到的对象
     * @throws IOException
     */
    public static List<Resource> getResources(String filePath) throws IOException {
        List<Resource> resources = new ArrayList<>();
        String[] split = filePath.split(",");
        for (String mapperXmlLocation : split) {
            Resource[] resourceArr = RESOLVER.getResources(mapperXmlLocation);
            resources.addAll(Arrays.asList(resourceArr));
        }
        return resources;
    }

    /**
     * 读取resources下所有相同名字的properties文件，返回一个Properites对象
     *
     * @param filePath 文件路径
     * @return 得到的对象
     * @throws IOException
     */
    public static Resource[] getResourceArr(String filePath) throws IOException {
        List<Resource> resources = getResources(filePath);
        return resources.toArray(new Resource[resources.size()]);
    }

    /**
     * 读取resources下所有相同名字的properties文件，返回一个Properites对象
     *
     * @param fileName properties文件名（文件必须要在resources文件夹下）
     * @return 得到的对象
     * @throws IOException
     */
    public static Properties getProperties(String fileName) throws IOException {
        return PROPERTIES_UTILS_INTERFACE.getProperties(fileName);
    }

    /**
     * 读取resources下所有相同名字的properties文件，返回一个Properites对象
     *
     * @param fileName  properties文件名（文件必须要在resources文件夹下）
     * @param encoding  字符编码
     * @return 得到的对象
     * @throws IOException
     */
    public static Properties getProperties(String fileName, String encoding) throws IOException {
        return PROPERTIES_UTILS_INTERFACE.getProperties(fileName, encoding);
    }

    /**
     * 根据properties文件输入流获取Properties对象
     *
     * @param file 文件
     * @return 得到的Properties对象
     * @throws IOException
     */
    public static Properties getProperties(File file) throws IOException {
        return PROPERTIES_UTILS_INTERFACE.getProperties(file);
    }

    /**
     * 根据properties文件输入流获取Properties对象
     *
     * @param file 文件
     * @param encoding  字符编码
     * @return 得到的Properties对象
     * @throws IOException
     */
    public static Properties getProperties(File file, String encoding) throws IOException {
        return PROPERTIES_UTILS_INTERFACE.getProperties(file, encoding);
    }

    /**
     * 根据properties文件路径获取Properties对象
     *
     * @param resource
     * @return 得到的Properties对象
     * @throws IOException
     */
    public static Properties getProperties(Resource resource) throws IOException {
        return PROPERTIES_UTILS_INTERFACE.getProperties(resource);
    }

    /**
     * 根据properties文件路径获取Properties对象
     *
     * @param resource
     * @param encoding  字符编码
     * @return 得到的Properties对象
     * @throws IOException
     */
    public static Properties getProperties(Resource resource, String encoding) throws IOException {
        return PROPERTIES_UTILS_INTERFACE.getProperties(resource, encoding);
    }

    /**
     * 根据properties文件路径获取Properties对象
     *
     * @param inputStream properties文件输入流
     * @return 得到的Properties对象
     * @throws IOException
     */
    public static Properties getProperties(InputStream inputStream) throws IOException {
        return PROPERTIES_UTILS_INTERFACE.getProperties(inputStream);
    }

    /**
     * 将带符号的字符串转换为数字
     *
     * @param value
     * @return
     */
    public static Object getNumberFormat(String value) {
        try {
            if (StringUtil.isBlankObject(value)) {
                return value;
            }
            return SE.eval(value);
        } catch (ScriptException e) {
            ExpUtil.throwEx(e);
            return value;
        }
    }

    /**
     * 获取properites文件中的某个值
     *
     * @param fileName properties文件名（文件必须要在resources文件夹下）
     * @param key 要获取的值的key
     * @return 得到的值
     * @throws IOException
     */
    public static String getValue(String fileName, String key) throws IOException {
        return PROPERTIES_UTILS_INTERFACE.getValue(fileName, key);
    }

    /**
     * 初始化某些属性的默认值
     *
     * @param properties
     */
    public static void initDefaultVal(Properties properties) {
        String keyPrefix = properties.getProperty(ConstantCache.KEY_PREFIX);
        if (StringUtil.isBlank(keyPrefix)) {
            properties.put(ConstantCache.KEY_PREFIX, "SojsonCache");
        }
    }

}